home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / black.box < prev    next >
Text File  |  1995-03-23  |  21KB  |  580 lines

  1. Article 5394 of comp.sys.handhelds:
  2. Path: en.ecn.purdue.edu!noose.ecn.purdue.edu!samsung!think.com!ames!uhccux!munnari.oz.au!metro!news
  3. From: peril@extro.ucc.su.OZ.AU (Peter Lisle)
  4. Newsgroups: comp.sys.handhelds
  5. Subject: Black Box game for the HP-48SX
  6. Message-ID: <1991Mar30.100309.8447@metro.ucc.su.OZ.AU>
  7. Date: 30 Mar 91 10:03:09 GMT
  8. Sender: news@metro.ucc.su.OZ.AU
  9. Organization: Uni Computing Service, Uni of Sydney, Australia
  10. Lines: 565
  11. Nntp-Posting-Host: extro.ucc.su.oz.au
  12.  
  13.  
  14. Black Box Game for the HP-48SX
  15. ==============================
  16.  
  17. This program is copyright (C) 1991 Chris Tham.
  18. Permission is given to copy, use or modify this program, as long as the
  19. original author is given credit.
  20.  
  21. Game Description
  22. ----------------
  23.  
  24. The Black Box is a large square containing grid of squares.  There are 8
  25. by 8 or 64 squares within the Black Box.  Four of these squares contain
  26. atoms.  You do not know where the four atoms are located within the
  27. black box.  Your task, should you decide to accept it, is to find the
  28. locations of the atoms within the Black Box.
  29.  
  30. Each square within the Black Box can be labelled by its coordinate
  31. position, as in Figure 1.
  32.  
  33.          1 2 3 4 5 6 7 8
  34.         +-+-+-+-+-+-+-+-+
  35.        1| | | | | | | | |
  36.         +-+-+-+-+-+-+-+-+
  37.        2| | | | | | | | |
  38.         +-+-+-+-+-+-+-+-+
  39.        3| | | | | | | | |
  40.         +-+-+-+-+-+-+-+-+
  41.        4| | | | | | | | |
  42.         +-+-+-+-+-+-+-+-+
  43.        5| | | | | | | | |
  44.         +-+-+-+-+-+-+-+-+
  45.        6| | | | | | | | |
  46.         +-+-+-+-+-+-+-+-+
  47.        7| | | | | | | | |
  48.         +-+-+-+-+-+-+-+-+
  49.        8| | | | | | | | |
  50.         +-+-+-+-+-+-+-+-+
  51.  
  52.        Figure 1: Coordinate labelling of squares in the black box
  53.  
  54. Hence the square on the upper left hand corner of the black box is
  55. labelled (1,1), the square on the upper right hand corner of the black
  56. box is labelled (1,8) and so on.
  57.  
  58. You can determine the location of atoms in the black box by firing rays
  59. into the black box from its sides.  Rays always enter the black box
  60. perpendicular to the side from which it is fired from.  Rays normally
  61. travel in a straight line whilst in the black box.  Depending on the
  62. location of atoms within the black box, the following may happen to a
  63. ray:
  64. 1. The ray may pass straight through on the other side of the box.
  65.    This usually (but not always!) means that the ray did not encounter
  66.    any atoms within or adjacent to its path.
  67.  
  68.                Ray leaves box here
  69.          1 2 3 ^ 5 6 7 8
  70.         +-+-+-+^+-+-+-+-+
  71.        1| | | |^| | | | |            Figure 2: Ray passing straight through
  72.         +-+-+-+^+-+-+-+-+
  73.        2| | | |^| | | | |
  74.         +-+-+-+^+-+-+-+-+
  75.        3| | | |^| | | | |
  76.         +-+-+-+^+-+-+-+-+
  77.        4| | | |^| | | | |
  78.         +-+-+-+^+-+-+-+-+
  79.        5| | | |^| | | | |
  80.         +-+-+-+^+-+-+-+-+
  81.        6| | | |^| | | | |
  82.         +-+-+-+^+-+-+-+-+
  83.        7| | | |^| | | | |
  84.         +-+-+-+^+-+-+-+-+
  85.        8| | | |^| | | | |
  86.         +-+-+-+^+-+-+-+-+
  87.                ^
  88.                Ray enters from here
  89.  
  90. 2. The ray may be absorbed.
  91.    A ray is absorbed if it collides with an atom in its path.
  92.  
  93.          1 2 3 4 5 6 7 8
  94.         +-+-+-+-+-+-+-+-+
  95.        1| | | | | | | | |            Figure 3: Ray absorption
  96.         +-+-+-+-+-+-+-+-+
  97.        2| | | | | | | | |
  98.         +-+-+-+-+-+-+-+-+
  99.        3| | | | | | | | |
  100.         +-+-+-+-+-+-+-+-+
  101.        4| | | |X| | | | |
  102.         +-+-+-+^+-+-+-+-+
  103.        5| | | |^| | | | |
  104.         +-+-+-+^+-+-+-+-+
  105.        6| | | |^| | | | |
  106.         +-+-+-+^+-+-+-+-+
  107.        7| | | |^| | | | |
  108.         +-+-+-+^+-+-+-+-+
  109.        8| | | |^| | | | |
  110.         +-+-+-+^+-+-+-+-+
  111.                ^
  112.                Ray enters from here
  113.  
  114. 3. The ray may be reflected back to the side it came from.
  115.    A ray is reflected if it encounters two atoms in front of it, one to
  116.    the left and the other to the right.
  117.  
  118.          1 2 3 4 5 6 7 8
  119.         +-+-+-+-+-+-+-+-+
  120.        1| | | | | | | | |            Figure 4: Ray reflection
  121.         +-+-+-+-+-+-+-+-+
  122.        2| | | | | | | | |
  123.         +-+-+-+-+-+-+-+-+
  124.        3| | | | | | | | |
  125.         +-+-+-+-+-+-+-+-+
  126.        4| | |X| |X| | | |
  127.         +-+-+-+^+-+-+-+-+
  128.        5| | | |^| | | | |
  129.         +-+-+-+^+-+-+-+-+
  130.        6| | | |^| | | | |
  131.         +-+-+-+^+-+-+-+-+
  132.        7| | | |^| | | | |
  133.         +-+-+-+^+-+-+-+-+
  134.        8| | | |^| | | | |
  135.         +-+-+-+^+-+-+-+-+
  136.                ^
  137.                Ray enters and leaves here
  138.  
  139. 4. The ray may be refracted and emerge on a different side of the black
  140.    box.
  141.    A ray is refracted when it encounters an atom in front of it, either
  142.    to the left or to the right.  Note that refractions are reflexive,
  143.    i.e. if you fire a ray and it gets refracted, you can fire a ray into
  144.    the location where the original ray emerged and it will emerge where
  145.    you had fired the original ray.
  146.  
  147.          1 2 3 4 5 6 7 8
  148.         +-+-+-+-+-+-+-+-+
  149.        1| | | | | | | | |            Figure 5: Ray refraction
  150.         +-+-+-+-+-+-+-+-+
  151.        2| | | | | | | | |
  152.         +-+-+-+-+-+-+-+-+
  153.        3| | | | | | | | |
  154.         +-+-+-+-+-+-+-+-+
  155.        4| | |X| | | | | |
  156.         +-+-+-+-+-+-+-+-+
  157.        5| | | |>>>>>>>>>> Ray emerges here
  158.         +-+-+-+^+-+-+-+-+
  159.        6| | | |^| | | | |
  160.         +-+-+-+^+-+-+-+-+
  161.        7| | | |^| | | | |
  162.         +-+-+-+^+-+-+-+-+
  163.        8| | | |^| | | | |
  164.         +-+-+-+^+-+-+-+-+
  165.                ^
  166.                Ray enters from here
  167.  
  168. Of course, a ray may get refracted, then absorbed, and so on.  By firing
  169. rays at strategic locations into the black box, you should be able to
  170. deduce the correct locations of the four atoms.
  171.  
  172. At the start of the game, the program will draw the black box on the
  173. screen and choose the locations of the four atoms randomly.  The object
  174. of the game is to be able to guess correctly the location of all four
  175. atoms within the black box by firing less than or equal to eight rays.
  176. Each time you fire a ray, the program traces its progress in the black
  177. box and informs you what happened to the ray (where it emerges or has
  178. been absorbed).  You may submit a guess of an atom's location at any
  179. time in the game.  If your guess is correct, the program will plot the
  180. atom on the black box.  If your guess is wrong, you lose immediately. 
  181. You win if you manage to guess all four atom locations correctly.  You
  182. lose if you run out of rays.
  183.  
  184. How to download the game into the HP-48SX
  185. -----------------------------------------
  186.  
  187. Download the file at the end of this document as 'BBOX'.  Enter into the
  188. directory, press the VAR key to get a list of variables.  Press the soft
  189. key corresponding 'INIT' to execute the initialization routine.
  190. [Warning: this will take a while].  After executing INIT, the game will
  191. be properly set up on the HP-48SX.
  192.  
  193. How to play the game
  194. --------------------
  195.  
  196. Press the soft key corresponding to 'PLAY'.  The HP-48SX screen will
  197. show a blank black box together with game credits.  The numeral `4' at
  198. the bottom side of the black box should be inversed.  This is where the
  199. cursor defaults to at the start of the game.  You can move the cursor by
  200. using the arrow keys on the keyboard.  The cursor always inverses
  201. whatever is lying underneath it.  You can move the cursor into the box
  202. as well as any location on the side of the box except at the corners. 
  203.  
  204. Pressing the ENTER key when the cursor is at the side of the box will
  205. fire a ray into the box from the location of the cursor.  Rays are
  206. labelled from A to H.  The program will trace the movement of the ray
  207. and label the location where the ray emerges with the same letter.
  208.  
  209. Pressing the ENTER key when the cursor is within the box will cause the
  210. program to check whether the square underneath the cursor contains an
  211. atom.  If it does, the program informs you, draws a cross at the
  212. location of the atom and lets the game continue. 
  213. If it doesn't, you lose immediately.
  214.  
  215. Pressing the <- key (the one next to the DEL key) causes the game to
  216. exit immediately.
  217.  
  218. Program description
  219. -------------------
  220.  
  221. The program uses two global variables which you can change to customise
  222. the game.  'NATOMS' contains the number of atoms that the program puts
  223. into the black box and consequently the number of atoms that you have
  224. to guess.  The default value of 'NATOMS' is 4.  'MAXRAYS' contains the
  225. maximum number of rays that you can fire into the black box.  The
  226. default value of 'MAXRAYS' is 8.  The INIT program generates the cursor
  227. mask grob (using the program GENMASK) and the cross grob (using the
  228. program GENCROS) as well as generating the PICT for the playing screen 
  229. (using the program GENBOX).  It then creates some global variables
  230. needed by the program and then reorders the variables in the directory.
  231. Finally, it deletes the initialization programs that are no longer
  232. needed during game play, including itself, in order to conserve memory.
  233.  
  234. The main program PLAY calls GENATOMS to generate NATOMS worth of atoms
  235. on the screen.  The atom locations are stored as complex numbers in a
  236. list called ATOMS.  GENATOMS does make sure that each atom occupies a
  237. position in the black box not occupied by any other atom.
  238.  
  239. PLAY then calls DBOX to put the playing screen PICT (stored in SCREEN) up. 
  240. Finally, PLAY calls MAIN which actually plays the game.
  241.  
  242. MAIN initializes two variables called NRAYS (containing the number of
  243. rays that the user has fired) and NGUESS (containing the number of
  244. guesses that the user has entered which are correct).  MAIN also does
  245. keyboard processing.  If the user presses the ENTER key, MAIN calls
  246. PROCESS which calls TRACERAY if the ENTER key was pressed whilst the
  247. cursor was on a side rather than within the black box.  If the user
  248. loses or quits the game, DRAWATOMS draws the locations of all atoms on
  249. the screen by marking them with crosses.
  250.  
  251. Helper routines are NRAND, WRITE1, WRITE2, PUTSTR, PUTCROS, GETPOS and
  252. PUTMASK.
  253.  
  254. Bugs
  255. ----
  256.  
  257. If you managed to make one correct atom guess, you can win the game by
  258. repeatedly guessing at the same location until NATOMS reaches MAXATOMS.
  259. The program does not check that you have already guessed at that location.
  260. However, if you did that, you are merely cheating yourself.
  261.  
  262. Author
  263. ------
  264. Chris Tham
  265. 30th of March 1991
  266.  
  267. Author's comments
  268. -----------------
  269. BBOX is my first non trivial programming project on the HP-48SX, so
  270. please excuse me for any stupid coding styles or inefficiencies.  The
  271. program is extensively commented and should be reasonably easy to read.
  272.  
  273. --- cut here ---
  274. %%HP: T(3)A(D)F(.);
  275. DIR @ Black box program
  276.     @ Copyright (C) 1991 Chris Tham
  277.     @ BYTES: 4398 # 16459d
  278.   PLAY @ Main routine for playing game
  279.     \<<
  280.       RCLF 'FLGS' STO             @ Store system and user flags
  281.       STD DEC                     @ Set standard display mode, decimal base
  282.       GENATOMS DBOX MAIN          @ Play game
  283.       FLGS STOF                   @ Restore system and user flags
  284.       3 FREEZE                    @ Freeze display until key pressed
  285.     \>>
  286.   NATOMS 4 @ number of atoms to be generated
  287.   MAXRAYS 8 @ maximum number of rays user can fire
  288.   INIT @ Generate things needed for game
  289.     \<<
  290.       RCLF 'FLGS' STO             @ Store system and user flags
  291.       STD DEC                     @ Set standard display mode, decimal base
  292.       GENMASK                     @ Generate mask for cursor
  293.       GENCROS                     @ Generate cross for displaying atom
  294.       GENBOX                      @ Generate playing screen
  295.       { } 'ATOMS' STO
  296.       0 'NGUESS' STO
  297.       0 'NRAYS' STO               @ Initialize variables
  298.       { PLAY NATOMS MAXRAYS GENATOMS DBOX MAIN PROCESS TRACERAY
  299.         DRAWATOMS NRAND WRITE1 WRITE2 PUTSTR PUTCROS GETPOS PUTMASK
  300.         CROS MASK SCREEN ATOMS NGUESS NRAYS FLGS }
  301.       ORDER                       @ We want the important vars in front }
  302.       'INIT' PURGE
  303.       'GENMASK' PURGE
  304.       'GENCROS' PURGE
  305.       'GENBOX' PURGE              @ Throw aways things we don't need
  306.       FLGS STOF                   @ Restore system and user flags
  307.     \>>
  308.   GENATOMS @ Generate list of atoms
  309.     \<<
  310.       { } 'ATOMS' STO             @ Initialise ATOMS to an empty list
  311.       0 \-> i                     @ zero number of atoms created
  312.       \<<
  313.         DO
  314.           1 8 NRAND
  315.           1 8 NRAND
  316.           R\->C                   @ generate random atom position
  317.           IF ATOMS OVER POS NOT   @ make sure atom not already in list
  318.           THEN
  319.             'ATOMS' STO+          @ add atom to list
  320.             'i' INCR DROP         @ increment number of atoms generated
  321.           END
  322.         UNTIL i NATOMS ==         @ stop when we have generated NATOMS atoms
  323.         END
  324.       \>>
  325.     \>>
  326.   DBOX
  327.     \<<
  328.       SCREEN PICT STO
  329.       { # 0d # 0d } PVIEW
  330.     \>>
  331.   MAIN @ main playing loop
  332.     \<<
  333.       (4,9) \-> p                 @ Default starting cursor position
  334.       \<<
  335.         0 'NRAYS' STO             @ Initialise number of rays fired
  336.         0 'NGUESS' STO            @ Initialise number of correct atom guesses
  337.         DO
  338.           p PUTMASK               @ Put cursor
  339.           0 WAIT                  @ Wait for keystroke
  340.           p PUTMASK               @ Hide cursor
  341.           CASE
  342.           DUP 34.1 ==             @ Left arrow
  343.           p RE 0 \=/ AND          @ Not at left edge
  344.           p (1,0) \=/ AND         @ Not entering undefined region
  345.           p (1,9) \=/ AND
  346.             THEN (-1,0) END       @ Move one position left
  347.           DUP 36.1 ==             @ Right arrow
  348.           p RE 9 \=/ AND          @ Not at right edge
  349.           p (8,0) \=/ AND         @ Not entering undefined region
  350.           p (8,9) \=/ AND
  351.             THEN (1,0) END        @ Move one position right
  352.           DUP 25.1 ==             @ Up arrow
  353.           p IM 0 \=/ AND          @ Not at top edge
  354.           p (0,1) \=/ AND         @ Not entering undefined region
  355.           p (9,1) \=/ AND
  356.             THEN (0,-1) END       @ Move one position up
  357.           DUP 35.1 ==             @ Down arrow
  358.           p IM 9 \=/ AND          @ Not at bottom edge
  359.           p (0,8) \=/ AND         @ Not entering undefined region
  360.           p (9,8) \=/ AND
  361.             THEN (0,1) END        @ Move one position down
  362.           DUP 51.1 ==             @ ENTER key
  363.             THEN
  364.               p PROCESS           @ process ENTER key
  365.               IF DUP (0,0) \=/    @ if not zero then store as new position
  366.                 THEN 'p' STO (0,0) END
  367.             END
  368.             (0,0)                 @ don't move from stored position
  369.           END
  370.           'p' STO+                @ changed current position
  371.         UNTIL 55.1 ==             @ Quit key pressed
  372.               NRAYS MAXRAYS > OR  @ maximum number of rays fired
  373.               NGUESS NATOMS == OR @ correct number of atoms guessed
  374.         END
  375.         PICT { # 70d # 40d }      @ Position in which to write message
  376.         CASE
  377.         NGUESS NATOMS ==          @ User won
  378.           THEN "You Win" END
  379.         NRAYS MAXRAYS >           @ User lost
  380.           THEN
  381.             DRAWATOMS
  382.             "You Lose"
  383.           END
  384.           DRAWATOMS               @ User quitted
  385.           "You Quit"
  386.         END
  387.         2 \->GROB REPL            @ Write message
  388.       \>>
  389.     \>>
  390.   PROCESS @ Handle processing when ENTER key is pressed
  391.     \<<
  392.       PICT { # 70d # 48d } # 60d # 16d BLANK REPL
  393.       IF DUP RE 0 ==              @ if we are at edge of grid
  394.          OVER RE 9 == OR
  395.          OVER IM 0 == OR
  396.          OVER IM 9 == OR
  397.       THEN                        @ fire off ray and check results
  398.         NRAYS 65 + CHR            @ convert ray number into alphabetic character
  399.         DUP2 SWAP PUTSTR          @ replace current character at edge
  400.         DUP2 "Ray " SWAP + SWAP \->STR + WRITE1 @ Write Ray N(x,y)
  401.         SWAP DUP TRACERAY         @ Trace movement of ray
  402.         CASE
  403.         DUP (0,0) ==
  404.           THEN
  405.             "Absorbed" WRITE2
  406.             DROP SWAP DROP        @ throw away Ray character and start position
  407.           END
  408.         DUP2 ==
  409.           THEN
  410.             "Reflected" WRITE2
  411.             SWAP DROP SWAP DROP   @ throw away Ray character and start position
  412.           END
  413.           SWAP DROP "To " OVER \->STR + WRITE2
  414.           SWAP OVER PUTSTR        @ put Ray character at end of ray
  415.         END
  416.         'NRAYS' INCR DROP         @ Increment number of rays fired
  417.       ELSE
  418.         "Atom " OVER \->STR + WRITE1 @ write Atom (x,y)
  419.         IF ATOMS OVER POS         @ is guess correct
  420.         THEN
  421.           DUP PUTCROS             @ yes, put a cross at location
  422.           'NGUESS' INCR DROP      @ increment number of correct guesses
  423.           "Correct"               @ print this string
  424.         ELSE
  425.           MAXRAYS 1 + 'NRAYS' STO           @ finish off the user
  426.           "Wrong"
  427.         END WRITE2
  428.       END
  429.     \>>
  430.   TRACERAY @ trace path of ray fired
  431.     \<<
  432.       (0,0) \-> r m               @ local variables
  433.       \<<
  434.         CASE
  435.         r RE 0 ==                 @ determine which direction ray goes
  436.           THEN (1,0) END
  437.         r RE 9 ==
  438.           THEN (-1,0) END
  439.         r IM 0 ==
  440.           THEN (0,1) END
  441.         r IM 9 ==
  442.           THEN (0,-1) END
  443.           "Illegal ray" DOERR
  444.         END
  445.         DO
  446.           DUP RE (0,1) (1,0) IFTE @ find direction perpendicular to ray
  447.           'm' STO
  448.           DUP r + DUP DUP
  449.           6                       @ Flag 6 is set if ray is deflected
  450.           IF SWAP m + ATOMS SWAP POS
  451.           THEN SF
  452.           ELSE CF
  453.           END
  454.           7                       @ Flag 7 is set if ray is deflected
  455.           IF SWAP m - ATOMS SWAP POS
  456.           THEN SF
  457.           ELSE CF
  458.           END
  459.           CASE
  460.           ATOMS SWAP POS          @ if atom in front of ray then absorb ray
  461.             THEN DROP r NEG END
  462.           6 FS? 7 FS? AND         @ if both flags set then reflect ray
  463.             THEN NEG END
  464.           7 FS?                   @ otherwise deflect ray depending on flag
  465.             THEN DROP m END
  466.           6 FS?
  467.             THEN DROP m NEG END
  468.           END
  469.           DUP 'r' STO+            @ get new ray position
  470.         UNTIL r RE 0 ==           @ until we reach an edge
  471.               r RE 9 == OR
  472.               r IM 0 == OR
  473.               r IM 9 == OR
  474.         END
  475.         DROP r                    @ return final position
  476.       \>>
  477.     \>>
  478.   DRAWATOMS @ Draw current location of all atoms
  479.     \<<
  480.       1 NATOMS
  481.       FOR i
  482.         ATOMS i GET PUTCROS       @ put a cross for every atom
  483.       NEXT
  484.     \>>
  485.   NRAND @ Generate random number from m to n
  486.     \<<
  487.       \-> M N
  488.       \<<
  489.         N M - 1 + RAND * IP M +
  490.       \>>
  491.     \>>
  492.   WRITE1 @ Write string in Area 1 of display
  493.     \<<
  494.       PICT { # 70d # 48d } ROT 2 \->GROB REPL
  495.     \>>
  496.   WRITE2 @ Write string in Area 2 of display
  497.     \<<
  498.       PICT { # 70d # 56d } ROT 2 \->GROB REPL
  499.     \>>
  500.   PUTSTR @ Put string in level 2 at cursor position in level 1
  501.     \<<
  502.       GETPOS                      @ get coordinates of cursor position
  503.       ROT 1 \->GROB               @ convert string to graphics object
  504.       # 5d # 5d BLANK             @ create a blank clip window
  505.       { # 1d # 0d } ROT REPL      @ clip string in window
  506.       REPL                        @ draw string
  507.     \>>
  508.   PUTCROS @ Put a cross mark at cursor position
  509.     \<<
  510.       GETPOS CROS REPL
  511.     \>>
  512.   GETPOS @ get PICT position given cursor position
  513.     \<<
  514.       C\->R
  515.       6 * 1 + R\->B
  516.       SWAP 6 * 1 + R\->B
  517.       SWAP 2 \->LIST
  518.       PICT SWAP
  519.     \>>
  520.   PUTMASK @ XOR mask onto PICT
  521.     \<<
  522.       GETPOS MASK GXOR
  523.     \>>
  524.   GENMASK @ Generate cursor mask
  525.     \<<
  526.       # 5d # 5d BLANK PICT STO    @ create 5x5 blank grob
  527.       0 4
  528.       FOR i                       @ fill each pixel
  529.         0 4 FOR j
  530.           i R\->B
  531.           j R\->B
  532.           2 \->LIST PIXON
  533.         NEXT
  534.       NEXT
  535.       PICT { # 0d # 0d } { # 4d # 4d } SUB
  536.       'MASK' STO                  @ store in variable name
  537.     \>>
  538.   GENCROS @ Generate cross mark
  539.     \<<
  540.       # 5d # 5d BLANK PICT STO    @ create 5x5 blank grob
  541.       0 4                         @ draw the cross pixel at a time
  542.       FOR i
  543.         i R\->B DUP DUP DUP
  544.         2 \->LIST PIXON
  545.         4 SWAP - 2 \->LIST PIXON
  546.       NEXT
  547.       PICT { # 0d # 0d } { # 4d # 4d } SUB
  548.       'CROS' STO                  @ store in variable name
  549.     \>>
  550.   GENBOX @ create main playing screen
  551.     \<<
  552.       # 131d # 64d BLANK PICT STO
  553.       1 8
  554.       FOR i
  555.         6 i * 1 + R\->B           @ calculate # 6 * i + 1
  556.         i 1 \->GROB               @ create grob from i in smallest font
  557.         PICT # 2d 4 PICK 2 \->LIST 3 PICK REPL
  558.         PICT # 56d 4 PICK 2 \->LIST 3 PICK REPL
  559.         SWAP 1 + SWAP
  560.         PICT 3 PICK # 1d 2 \->LIST 3 PICK REPL
  561.         PICT SWAP ROT # 55d 2 \->LIST SWAP REPL
  562.       NEXT
  563.       6 56                        @ Draw lines of grid
  564.       FOR i
  565.         i R\->B
  566.         # 6d OVER 2 \->LIST
  567.         # 54d 3 PICK 2 \->LIST LINE
  568.        DUP # 6d 2 \->LIST
  569.        SWAP # 54d 2 \->LIST LINE
  570.       6 STEP
  571.       PICT { # 76d # 0d } "Black Box" 3 \->GROB REPL
  572.       PICT { # 100d # 10d } "(C) 1990" 1 \->GROB REPL
  573.       PICT { # 90d # 16d } "Chris Tham" 1 \->GROB REPL
  574.       PICT RCL 'SCREEN' STO       @ Store in SCREEN variable
  575.     \>>
  576. END
  577. --- cut here ---
  578.  
  579.  
  580.